package com.hsh.tools.file;

import com.hsh.tools.DateUtils;
import com.hsh.tools.FinalData;
import com.hsh.tools.handler.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 上传文件
 *
 * @author 黄思海
 * @date 2021/7/9
 */
//@SuppressWarnings("unused")
public class UploadFileUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(UploadFileUtils.class);

    //测试文件 1.上传  2.下载 3.删除  4.转移[复制] 5.转移[复制,且删除原地址的文件]

    /**
     * @param prefixPath 文件路径前缀[以 '/' 结尾]
     * @return 生成文件所存储的地址(年月日)
     */
    public static String createDirectory(String prefixPath) {
        String yyyyMMdd = DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT_YYYY_MM_DD_SLASH) + "/";
        File file = new File(prefixPath + yyyyMMdd);
        if (!file.exists()) {
            boolean mkdirs = file.mkdirs();
        }
        LOGGER.info("file full path: {} " + prefixPath + yyyyMMdd);
        return prefixPath + yyyyMMdd;
    }

    /**
     * @param file             文件流
     * @param servicePath      服务器保存路径  /mnt/drbox/data/../
     * @param orderProcessPath /mnt/drbox/data/
     * @param orderProcessUrl  http://172.18.10.102:7003/
     * @return 上传文件的信息
     */
    public static FileDataResult uploadSingleFile(MultipartFile file, String servicePath, String orderProcessPath, String orderProcessUrl) {
        try {
            // 1.服务器存储的地址
            servicePath = createDirectory(servicePath);
            if (Objects.isNull(file) || Objects.isNull(file.getOriginalFilename()))
                throw new BusinessException("file is null");
            // 2.原文件名称
            String oldFileName = file.getOriginalFilename();
            // 3.原文件单独的文件名称
            String oldSingleFileName = oldFileName.substring(0, oldFileName.lastIndexOf("."));
            // 4.文件后缀 .jpg ...
            String fileSuffix = oldFileName.substring(oldFileName.lastIndexOf(".") - 1);
            // 5.服务器存储的文件名称+后缀
            String dataName = UUID.randomUUID().toString().replace("-", "") + fileSuffix;
            // 6.服务器存储的地址+后缀
            String servicePathName = servicePath + dataName;
            file.transferTo(new File(servicePathName));
            // 7. 网页访问的路径地址  http://a/../jpg
            String dataUrl = servicePathName.replace(orderProcessPath, orderProcessUrl);
            // 8. /a/../jpg
            String dataFileName = servicePathName.replace(orderProcessPath, "");

            FileDataResult result = new FileDataResult();
            result.setServicePath(servicePath);
            result.setOldFileName(oldFileName);
            result.setOldSingleFileName(oldSingleFileName);
            result.setFileSuffix(fileSuffix);
            result.setDataName(dataName);
            result.setDataUrl(dataUrl);
            result.setServicePathName(servicePathName);
            result.setDataFileName(dataFileName);
            return result;
        } catch (IOException e) {
            LOGGER.error("file upload fail: {} ", e.getMessage());
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 文件的复制[若重复则--> uuid__源文件.jpg]
     *
     * @param resource 文件的全路径(加图片名称)  /mnt/drbox/data/../1.jpg
     * @param target   目标文件路径   /a/b/c/d/../
     */
    public static void copyFile(String resource, String target) {
        if (!new File(resource).exists()) {
            LOGGER.error("file not exists");
            return;
        }
        File filePath = new File(target);
        if (!filePath.exists()) {
            filePath.mkdirs();
        }
        // 获取源文件的名称
        String newFileName = resource.substring(resource.lastIndexOf(File.separator) + 1); //目标文件地址
        // 判断是否存在的标记
        String disposeTarget = target + File.separator + newFileName;
        if (new File(disposeTarget).exists()) {
            String replace = UUID.randomUUID().toString().replace("-", "");
            target = target + File.separator + replace + FinalData.UPLOAD_FILE_REPETITION_FLAG + newFileName;
        } else {
            target = target + File.separator + newFileName;
        }
        try {
            FileInputStream fis = new FileInputStream(resource);// 创建输入流对象
            FileOutputStream fos = new FileOutputStream(target); // 创建输出流对象
            byte[] dataS = new byte[1024 * 8];// 创建搬运工具
            int len = 0;//创建长度
            while ((len = fis.read(dataS)) != -1) {// 循环读取数据
                fos.write(dataS, 0, len);
            }
            fis.close();// 释放资源
        } catch (Exception e) {
            LOGGER.error("file copy or move fail: {} ", e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 删除文件
     *
     * @param servicePath 服务器地址[以 '/' 结尾]
     * @param fileName    文件名称
     */
    public static void delFile(String servicePath, String fileName) {
        File file = new File(servicePath.concat(fileName));
        LOGGER.info("filePath: {}", servicePath.concat(fileName));
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                LOGGER.info("file {} delete success", fileName);
            } else {
                LOGGER.error("file {} delete fail", fileName);
            }
        } else {
            LOGGER.info("file {} not exists", fileName);
        }
    }

    /**
     * @param string 原字符串
     * @param index  第几次出现
     * @param flag   符号标记
     * @return 返回 flag 在原字符串中第 index 出现的位置
     */
    public static int getCharacterPosition(String string, Integer index, String flag) {
        //这里是获取 flag 符号的位置
        Matcher slashMatcher = Pattern.compile(flag).matcher(string);
        int mIdx = 0;
        while (slashMatcher.find()) {
            mIdx++;
            //当 flag 符号第三次出现的位置
            if (mIdx == index) {
                break;
            }
        }
        return slashMatcher.start();
    }

}
